// encoder.cpp
// Copyright (C) 2008 Sam Bateman
// samuel.bateman@gmail.com
//
// This file is part of DVD On Fire.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

//! @file encoder.cpp
//! @author Sam Bateman
//! @brief Source file for the Encoder class.

#include <cstdio>
#include <string>
#include <libdvdonfire/config.h>
#include <libdvdonfire/log.h>
#include <libdvdonfire/process.h>
#include <libdvdonfire/util.h>
#include "encoder.h"
using namespace dvdonfire::lib;
using namespace std;

namespace dvdonfire
{
    namespace daemon
    {
        // struct Encoder::Impl {{{
        struct Encoder::Impl
        {
            Process *process;
        };
        // }}}
        // Encoder::Encoder() {{{
        //! @brief Constructor.
        Encoder::Encoder()
        : Step("Encoder")
        {
            impl = new Impl;
            impl->process = NULL;
        }
        // }}}
        // Encoder::~Encoder() {{{
        //! @brief Destructor.
        Encoder::~Encoder()
        {
            delete impl->process;
            delete impl;
        }
        // }}}
        // Encoder::cleanup() {{{
        //! @brief Removes the original .mpg file.
        void Encoder::cleanup()
        {
        }
        // }}}
        // Encoder::doStep() {{{
        //! @brief Converts the .mpg file to DVD format.
        //!
        //! Uses ffmpeg to re-encode the video file from Decoder into a
        //! properly formated DVD-Video mpeg file.  This function runs in a
        //! separate thread.
        void Encoder::doStep()
        {
            while (impl->process->isRunning()){
                if (yield()) return;
            }
        }
        // }}}
        // Encoder::start() {{{
        //! @brief Starts the ffmpeg subprocess.
        //!
        //! Starts the ffmpeg child process to do video conversion.
        void Encoder::start()
        {
            // get the files
            Config *config = getData()->getConfig();
            string temp_dir = config->get("confdir") + "tmp/";
            string input_file = temp_dir + "dtout.mpg";
            string output_file = temp_dir + "etout.mpg";

            // create the ffmpeg process
            size_t num_args = 9;
            const string args[] = {
                "./ffmpeg",
                "-i", input_file,
                "-target", "ntsc-dvd",
                "-aspect", "4:3",
                "-y",
                output_file,
            };
            logArgs(args, num_args);
            impl->process = new Process(args, num_args);

            // Step does the rest
            Step::start();
        }
        // }}}
        // Encoder::stop() {{{
        //! @brief Starts the ffmpeg subprocess.
        //!
        //! Starts the ffmpeg child process to do video conversion.
        void Encoder::stop()
        {
            Step::stop();
            impl->process->kill();
        }
        // }}}
    }
}
